package com.asiainfo.dacp.datastash.domain.stepdefine.service;

import com.asiainfo.dacp.core.BeanFactory;
import com.asiainfo.dacp.metamodel.domain.ds.model.MetaDataSource;
import com.asiainfo.dacp.metamodel.open.vo.EnumVo;
import com.asiainfo.dacp.metamodel.open.vo.OptionVo;
import com.google.gson.*;
import com.google.gson.stream.JsonReader;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;

import java.util.*;
import java.util.Map.Entry;
import java.io.StringReader;
import java.lang.reflect.Method;

/**
 * Created by winter on 2017/12/27.
 */
@Service
public class DataStashStepDefineStepCfgService {
    private  Gson gson=new Gson();

    public String  initOptions(String stepCfg)throws Exception{
        JsonElement jsonEle = new JsonParser().parse(stepCfg);
        JsonElement el=replaceKey(jsonEle,"optionClass","options");
        return  gson.toJson(el);
    }

    public  JsonElement replaceKey(JsonElement source, String  rep,String optionKeyName) throws Exception{
        if (source == null || source.isJsonNull()) {
            return JsonNull.INSTANCE;
        }
        if (source.isJsonPrimitive()) {
            return source;
        }
        if (source.isJsonArray()) {
            JsonArray jsonArr = source.getAsJsonArray();
            JsonArray jsonArray = new JsonArray();
            for( JsonElement item:jsonArr ){
                jsonArray.add(replaceKey(item, rep,optionKeyName));
            }
            return jsonArray;
        }
        if (source.isJsonObject()) {
            JsonObject jsonObj = source.getAsJsonObject();
            Iterator<Entry<String, JsonElement>> iterator = jsonObj.entrySet().iterator();
            JsonObject newJsonObj = new JsonObject();
            while(iterator.hasNext()){
                Entry<String, JsonElement> item=iterator.next();
                String key = item.getKey();
                JsonElement value = item.getValue();
                if (rep.equalsIgnoreCase(key)) {
                    newJsonObj.add(optionKeyName,gson.toJsonTree(invoke(value.getAsString())));
                }
                newJsonObj.add(key,replaceKey(value, rep,optionKeyName));
            }
            return  newJsonObj;
        }
        return JsonNull.INSTANCE;
    }

    private  List<OptionVo> invoke(String path)throws  Exception{
        String[] pathobj=path.split(",");
        Object[] params=null;
        String className=pathobj[0];
        String methodName=pathobj[1];
        if(pathobj.length>2){
            params= Arrays.copyOfRange(pathobj, 2, pathobj.length);
        }
        Object obj=  BeanFactory.getBean(Class.forName(className));
        Class<?>  cls =obj.getClass();
        Method method = cls.getDeclaredMethod(methodName,String.class);
        List<OptionVo> optionVos=new ArrayList<OptionVo>();
        if(params==null){
            optionVos= (List<OptionVo>)method.invoke(obj);
        }else{
            optionVos= (List<OptionVo>)method.invoke(obj,params);
        }
        return    optionVos;
    }
}
